<template>
  <a-drawer
    v-model:visible="visible"
    :title="title"
    :mask-closable="false"
    :esc-to-close="false"
    :width="width >= 600 ? 600 : '100%'"
    :ok-button-props="{ disabled: !isRoleSelected }"
    @before-ok="save"
    @close="reset"
  >
    <a-form ref="formRef" :model="form" :rules="rules" size="large" auto-label-width>
      <a-form-item label="头像" field="avatar">
        <a-upload
          v-model:file-list="fileList"
          :custom-request="customUpload"
          list-type="picture-card"
          :show-upload-button="fileList.length < 1"
          accept="image/*"
        >
          <template #upload-button>
            <div class="upload-button">
              <icon-plus />
              <div class="upload-text">点击上传</div>
            </div>
          </template>
        </a-upload>
      </a-form-item>
      <a-form-item v-if="!isUpdate" label="工号" field="workId">
        <a-input v-model.trim="form.workId" placeholder="请输入工号" :max-length="64" />
      </a-form-item>
      <a-form-item label="姓名" field="realname">
        <a-input v-model.trim="form.realname" placeholder="请输入姓名" :max-length="30" />
      </a-form-item>
      <a-form-item v-if="!isUpdate" label="密码" field="password">
        <a-input-password v-model.trim="form.password" placeholder="请输入密码" :max-length="32" />
      </a-form-item>
      <a-form-item label="手机号码" field="phone">
        <a-input v-model.trim="form.phone" placeholder="请输入手机号码" :max-length="11" />
      </a-form-item>
      <a-form-item label="角色" field="roleIds">
        <a-select
          v-model="form.roleIds"
          :options="roleList"
          placeholder="请选择角色"
          multiple
          allow-clear
          value-key="value"
          :allow-search="{ retainInputValue: true }"
        />
      </a-form-item>
      <a-form-item label="状态" field="status">
        <a-switch
          v-model="form.status"
          :disabled="form.isSystem"
          :checked-value="1"
          :unchecked-value="2"
          checked-text="启用"
          unchecked-text="禁用"
          type="round"
        />
      </a-form-item>
    </a-form>
  </a-drawer>
</template>

<script setup lang="ts">
import { type FormInstance, Message } from '@arco-design/web-vue'
import type { FieldRule } from '@arco-design/web-vue/es/form/interface'
import type { FileItem, RequestOption, UploadRequest } from '@arco-design/web-vue/es/upload/interfaces'
import { useWindowSize } from '@vueuse/core'
import { addUser, getUser, updateUser } from '@/apis/system'
import { uploadAvatarFile } from '@/apis/common/common'
import type { Gender, Status } from '@/types/global'
import { useForm } from '@/hooks'
import { useRole } from '@/hooks/app'

const emit = defineEmits<{
  (e: 'save-success'): void
}>()
const { width } = useWindowSize()
const { roleList, getRoleList } = useRole()

const dataId = ref('')
const isUpdate = computed(() => !!dataId.value)
const title = computed(() => (isUpdate.value ? '修改用户' : '新增用户'))
const formRef = ref<FormInstance>()

const rules: Record<string, FieldRule[]> = {
  realname: [
    { required: true, message: '请输入昵称' },
    {
      match: /^[\w\u4E00-\u9FA5-]{2,30}$/,
      message: '昵称长度为 2-30 个字符，支持中文、字母、数字、下划线，短横线'
    }
  ],
  password: [{ required: true, message: '请输入密码' }],
  gender: [{ required: true, message: '请选择性别' }],
  roleIds: [{ required: true, message: '请选择角色' }],
  phone: [
    {
      match: /^$|^1[3-9]\d{9}$/,
      message: '手机号码格式错误'
    }
  ]
}

interface FormState {
  id?: number
  workId?: string
  realname: string
  password?: string
  phone: string
  gender: Gender
  roleIds: Array<number>
  status: Status
  avatar?: string
  isSystem?: boolean
}

const defaultForm: FormState = {
  workId: '',
  realname: '',
  password: '',
  phone: '',
  gender: 0,
  roleIds: [],
  status: 1
}

const { form, resetForm } = useForm(defaultForm)

const fileList = ref<FileItem[]>([])

// 自定义上传
const customUpload = (option: RequestOption): UploadRequest => {
  const formData = new FormData()
  const file = option.fileItem.file
  if (!file) {
    Message.error('请选择文件')
    option.onError()
    return {
      abort() {}
    }
  }

  formData.append('file', file)

  uploadAvatarFile(formData)
    .then((res) => {
      form.avatar = res.data
      fileList.value = [{
        uid: '1',
        name: file.name,
        url: res.data
      }]
      Message.success('上传成功')
      option.onSuccess()
    })
    .catch(() => {
      Message.error('上传失败')
      option.onError()
    })

  return {
    abort() {
      // 取消上传
    }
  }
}

// 重置
const reset = () => {
  formRef.value?.resetFields()
  resetForm()
}

const visible = ref(false)
// 新增
const onAdd = () => {
  if (!roleList.value.length) {
    getRoleList()
  }
  reset()
  dataId.value = ''
  visible.value = true
}

// 修改
const onUpdate = async (id: string, userRecord?: any) => {
  if (!roleList.value.length) {
    await getRoleList()
  }
  reset()
  dataId.value = id

  // 获取详情数据
  const res = await getUser(id)
  const data = res.data as any

  // 先重置表单
  resetForm()
  // 设置表单数据
  form.realname = data.realname
  form.phone = data.phone || ''
  form.gender = data.gender as Gender
  form.status = data.status || 1
  form.avatar = data.avatar

  // 优先从列表记录中获取角色信息
  if (userRecord && userRecord.roleIds && userRecord.roleIds.length > 0) {
    form.roleIds = [...userRecord.roleIds]
  }
  // 如果列表中没有，尝试从详情中获取
  else if (data.roleIds && data.roleIds.length > 0) {
    form.roleIds = [...data.roleIds]
  }
  // 如果详情中的roleIds也没有，尝试从roles数组中提取
  else if (data.roles && data.roles.length > 0) {
    form.roleIds = data.roles.map((role: any) => role.id)
  }
  // 如果都没有，但列表中有roleNames，创建提示信息
  else if (userRecord && userRecord.roleNames && userRecord.roleNames.length > 0) {
    // 角色不存在但有名称信息，提示用户重新选择
    const roleNames = userRecord.roleNames.join(', ')
    Message.warning(`请重新选择用户角色，原角色为: ${roleNames}`)
    form.roleIds = []
  } else {
    Message.warning('未找到用户角色信息，请重新选择')
    form.roleIds = []
  }

  form.isSystem = data.isSystem

  // 设置头像
  if (data.avatar) {
    fileList.value = [{
      uid: '1',
      name: 'avatar.png',
      url: data.avatar
    }]
  } else {
    fileList.value = []
  }
  visible.value = true
}

// 判断是否选择了角色
const isRoleSelected = computed(() => {
  return form.roleIds && form.roleIds.length > 0
})

// 保存
const save = async () => {
  try {
    await formRef.value?.validate()
    if (isUpdate.value) {
      await updateUser({
        id: Number(dataId.value),
        realname: form.realname,
        phone: form.phone || '',
        email: '',
        avatar: form.avatar || '',
        status: form.status,
        roleIds: form.roleIds
      })
    } else {
      await addUser({
        ...form,
        email: '',
        roleIds: form.roleIds
      })
    }
    Message.success('保存成功')
    emit('save-success')
    visible.value = false
    return true
  } catch {
    return false
  }
}

defineExpose({ onAdd, onUpdate })
</script>

<style lang="scss" scoped>
.avatar-upload {
  display: flex;
  flex-direction: column;
  gap: 8px;

  :deep(.arco-image) {
    border-radius: 4px;
    overflow: hidden;
  }
}

.avatar-wrapper {
  width: 200px;
  height: 100px;
  border: 1px dashed #d9d9d9;
  border-radius: 4px;
  cursor: pointer;
  transition: border-color 0.3s;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;

  &:hover {
    border-color: #165dff;
  }

  .avatar-placeholder {
    color: #999;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;

    .placeholder-text {
      margin-top: 8px;
      font-size: 12px;
    }
  }
}

.image-actions {
  position: absolute;
  top: 8px;
  right: 8px;
  display: none;
}

:deep(.arco-image):hover .image-actions {
  display: block;
}

.upload-button {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  color: #999;

  .upload-text {
    margin-top: 8px;
    font-size: 12px;
  }
}
</style>
